/**
 * @author Johannes Stigler <stigler@genzentrum.lmu.de>
 * @license AGPL-3.0
 */

import Prism from 'prismjs';
(function(Prism) {
  const str = {
    pattern: /"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,
    greedy: true,
  };
  const num = [
    /\b(?:[+-]?Inf|NaN)\b/i,
    /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,
  ];
  const op = /\$|c>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/;
  const punc = /[{}[\];(),.:]/;

  Prism.languages.igor = {
    'comment': /\/\/.*/,
    'string': str,
    'number': num,
    'operator': op,
    'punctuation': punc,
    'class-name': {
      pattern: /(\b(?:function|window|structure|macro)\s+)\w+/i,
      lookbehind: true,
    },
    'flowcontrol': {
      pattern: /\b(?<!#)(?:AbortOnRTE|AbortOnValue|break|catch|continue|default|do|while|endtry|for|endfor|if|else|elseif|endif|return|strswitch|case|endswitch|switch|try)\b/i,
      alias: 'keyword',
    },
    'language': {
      pattern: /\b(?<!\/)(?:Function|End|Macro|EndMacro|Structure|EndStructure|Picture|Proc|Window)\b/i,
      alias: 'keyword',
    },
    'hash-keyword': {
      pattern: /\B#(?:define|if|elif|endif|ifdef|else|endif|ifndef|include|pragma|undef)\b/i,
      alias: 'symbol',
	  },
    'other-keyword': {
      pattern: /\b(?<!\/)(?:Constant|DoPrompt|GalleryGlobal|IgorVersion|IndependenModule|Menu|ModuleName|MultiThread|Override|Popup|ProcGlobal|Prompt|Static|StrConstant|Submenu|Threadsafe|Version)\b/i,
      alias: 'keyword',
    },
    'local-variable-types': {
      pattern: /\b(?<!\/)(?:complex|double|int|int64|uint64|string|STRUCT|variable|DFREF|FUNCREF|NVAR|SVAR|WAVE)\b/i,
      alias: 'keyword',
    },
    'builtin-functions': {
      pattern: /\b(?:HDF5CheckDataClass|HDF5MakeHyperslabWave|InitHDF5DataInfo|HDF5DatasetRank|HDF5AttributeRank|InitHDF5DatatypeInfo|InitHDF5LinkInfoStruct|HDF5IsExternalLink|abs|acos|acosh|AiryA|AiryAD|AiryB|AiryBD|alog|area|areaXY|asin|asinh|atan|atan2|atanh|AxisValFromPixel|Besseli|Besselj|Besselk|Bessely|beta|betai|BinarySearch|BinarySearchInterp|binomial|binomialln|binomialNoise|cabs|CaptureHistoryStart|ceil|centerOfMass|centerOfMassXY|cequal|char2num|chebyshev|chebyshevU|CheckName|cmplx|cmpstr|conj|ContourZ|cos|cosh|cosIntegral|cot|coth|CountObjects|CountObjectsDFR|cpowi|CreationDate|csc|csch|DataFolderExists|DataFolderRefChanges|DataFolderRefsEqual|DataFolderRefStatus|date2secs|datetime|DateToJulian|Dawson|defined|deltax|digamma|dilogarithm|DimDelta|DimOffset|DimSize|e|ei|ellipticE|ellipticK|enoise|equalWaves|erf|erfc|erfcw|exists|exp|expInt|expIntegralE1|expNoise|factorial|Faddeeva|fakedata|faverage|faverageXY|FindDimLabel|FindListItem|floor|FontSizeHeight|FontSizeStringWidth|FresnelCos|FresnelSin|gamma|gammaEuler|gammaInc|gammaNoise|gammln|gammp|gammq|Gauss|Gauss1D|Gauss2D|gcd|GeometricMean|GetBrowserLine|GetDefaultFontSize|GetDefaultFontStyle|GetKeyState|GetRTError|GetRTLocation|GizmoInfo|GizmoScale|gnoise|GrepString|hcsr|HDF5AttributeInfo|HDF5DatasetInfo|HDF5LibraryInfo|HDF5LinkInfo|HDF5TypeInfo|hermite|hermiteGauss|HyperG0F1|HyperG1F1|HyperG2F1|HyperGNoise|HyperGPFQ|i|IgorVersion|imag|IndexToScale|Integrate1D|interp|Interp2D|Interp3D|inverseERF|inverseERFC|ItemsInList|j|JacobiCn|JacobiSn|Laguerre|LaguerreA|LaguerreGauss|LambertW|leftx|LegendreA|limit|ln|log|logNormalNoise|lorentzianNoise|magsqr|MandelbrotPoint|MarcumQ|MatrixCondition|MatrixDet|MatrixDot|MatrixRank|MatrixTrace|max|mean|median|min|mod|ModDate|MPFXEMGPeak|MPFXExpConvExpPeak|MPFXGaussPeak|MPFXLorentzianPeak|MPFXVoigtPeak|norm|NumberByKey|numpnts|numtype|NumVarOrDefault|NVAR_Exists|p|p2rect|PanelResolution|ParamIsDefault|pcsr|Pi|PixelFromAxisVal|pnt2x|poissonNoise|poly|poly2D|PolygonArea|q|qcsr|r|r2polar|real|rightx|round|s|sawtooth|scaleToIndex|ScreenResolution|sec|sech|SelectNumber|SetEnvironmentVariable|sign|sin|sinc|sinh|sinIntegral|SphericalBessJ|SphericalBessJD|SphericalBessY|SphericalBessYD|SphericalHarmonics|sqrt|StartMSTimer|StatsBetaCDF|StatsBetaPDF|StatsBinomialCDF|StatsBinomialPDF|StatsCauchyCDF|StatsCauchyPDF|StatsChiCDF|StatsChiPDF|StatsCMSSDCDF|StatsCorrelation|StatsDExpCDF|StatsDExpPDF|StatsErlangCDF|StatsErlangPDF|StatsErrorPDF|StatsEValueCDF|StatsEValuePDF|StatsExpCDF|StatsExpPDF|StatsFCDF|StatsFPDF|StatsFriedmanCDF|StatsGammaCDF|StatsGammaPDF|StatsGeometricCDF|StatsGeometricPDF|StatsGEVCDF|StatsGEVPDF|StatsHyperGCDF|StatsHyperGPDF|StatsInvBetaCDF|StatsInvBinomialCDF|StatsInvCauchyCDF|StatsInvChiCDF|StatsInvCMSSDCDF|StatsInvDExpCDF|StatsInvEValueCDF|StatsInvExpCDF|StatsInvFCDF|StatsInvFriedmanCDF|StatsInvGammaCDF|StatsInvGeometricCDF|StatsInvKuiperCDF|StatsInvLogisticCDF|StatsInvLogNormalCDF|StatsInvMaxwellCDF|StatsInvMooreCDF|StatsInvNBinomialCDF|StatsInvNCChiCDF|StatsInvNCFCDF|StatsInvNormalCDF|StatsInvParetoCDF|StatsInvPoissonCDF|StatsInvPowerCDF|StatsInvQCDF|StatsInvQpCDF|StatsInvRayleighCDF|StatsInvRectangularCDF|StatsInvSpearmanCDF|StatsInvStudentCDF|StatsInvTopDownCDF|StatsInvTriangularCDF|StatsInvUsquaredCDF|StatsInvVonMisesCDF|StatsInvWeibullCDF|StatsKuiperCDF|StatsLogisticCDF|StatsLogisticPDF|StatsLogNormalCDF|StatsLogNormalPDF|StatsMaxwellCDF|StatsMaxwellPDF|StatsMedian|StatsMooreCDF|StatsNBinomialCDF|StatsNBinomialPDF|StatsNCChiCDF|StatsNCChiPDF|StatsNCFCDF|StatsNCFPDF|StatsNCTCDF|StatsNCTPDF|StatsNormalCDF|StatsNormalPDF|StatsParetoCDF|StatsParetoPDF|StatsPermute|StatsPoissonCDF|StatsPoissonPDF|StatsPowerCDF|StatsPowerNoise|StatsPowerPDF|StatsQCDF|StatsQpCDF|StatsRayleighCDF|StatsRayleighPDF|StatsRectangularCDF|StatsRectangularPDF|StatsRunsCDF|StatsSpearmanRhoCDF|StatsStudentCDF|StatsStudentPDF|StatsTopDownCDF|StatsTriangularCDF|StatsTriangularPDF|StatsTrimmedMean|StatsUSquaredCDF|StatsVonMisesCDF|StatsVonMisesNoise|StatsVonMisesPDF|StatsWaldCDF|StatsWaldPDF|StatsWeibullCDF|StatsWeibullPDF|StopMSTimer|str2num|stringCRC|stringmatch|strlen|strsearch|StudentA|StudentT|sum|SVAR_Exists|t|TagVal|tan|tanh|TextEncodingCode|ThreadGroupCreate|ThreadGroupRelease|ThreadGroupWait|ThreadProcessorCount|ThreadReturnValue|ticks|trunc|UnsetEnvironmentVariable|Variance|vcsr|VoigtFunc|VoigtPeak|WaveCRC|WaveDims|WaveExists|WaveMax|WaveMin|WaveMinAndMax|WaveModCount|WaveRefsEqual|WaveTextEncoding|WaveType|WhichListItem|WinType|wnoise|x|x2pnt|xcsr|y|z|zcsr|ZernikeR|zeta|AddListItem|AnnotationInfo|AnnotationList|AxisInfo|AxisLabel|AxisList|Base64Decode|Base64Encode|CaptureHistory|ChildWindowList|CleanupName|ContourInfo|ContourNameList|ControlNameList|ConvertTextEncoding|CreateDataObjectName|CsrInfo|CsrWave|CsrXWave|CTabList|DataFolderDir|DataFolderList|date|FetchURL|FontList|FuncRefInfo|FunctionInfo|FunctionList|FunctionPath|GetBrowserSelection|GetDataFolder|GetDefaultFont|GetDimLabel|GetEnvironmentVariable|GetErrMessage|GetFormula|GetIndependentModuleName|GetIndexedObjName|GetIndexedObjNameDFR|GetRTErrMessage|GetRTLocInfo|GetRTStackInfo|GetScrapText|GetUserData|GetWavesDataFolder|GetWindowBrowserSelection|GrepList|GuideInfo|GuideNameList|Hash|IgorInfo|ImageInfo|ImageNameList|IndependentModuleList|IndexedDir|IndexedFile|JulianToDate|LayoutInfo|ListMatch|LowerStr|MacroList|NameOfWave|NormalizeUnicode|note|num2char|num2istr|num2str|OperationList|PadString|ParseFilePath|PathList|PICTInfo|PICTList|PossiblyQuoteName|ProcedureText|RemoveByKey|RemoveEnding|RemoveFromList|RemoveListItem|ReplaceNumberByKey|ReplaceString|ReplaceStringByKey|ReplicateString|Secs2Date|Secs2Time|SelectString|SortList|SpecialCharacterInfo|SpecialCharacterList|SpecialDirPath|StringByKey|StringFromList|StringList|StrVarOrDefault|TableInfo|TextEncodingName|TextFile|ThreadGroupGetDF|time|TraceFromPixel|TraceInfo|TraceNameList|TrimString|UniqueName|UnPadString|UpperStr|URLDecode|URLEncode|VariableList|WaveDataToString|WaveHash|WaveInfo|WaveList|WaveName|WaveRefWaveToList|WaveUnits|WinList|WinName|WinRecreation|XWaveName|ContourNameToWaveRef|CsrWaveRef|CsrXWaveRef|ImageNameToWaveRef|ListToTextWave|ListToWaveRefWave|NewFreeWave|StringToUnsignedByteWave|TagWaveRef|TraceNameToWaveRef|WaveRefIndexed|WaveRefIndexedDFR|XWaveRefFromTrace|GetDataFolderDFR|GetWavesDataFolderDFR|NewFreeDataFolder|ThreadGroupGetDFR)\b/i,
      alias: 'function',
    },
    'builtin-operations': {
      pattern: /\b(?:Abort|AddFIFOData|AddFIFOVectData|AddMovieAudio|AddMovieFrame|AddWavesToBoxPlot|AddWavesToViolinPlot|AdoptFiles|APMath|Append|AppendBoxPlot|AppendImage|AppendLayoutObject|AppendMatrixContour|AppendText|AppendToGizmo|AppendToGraph|AppendToLayout|AppendToTable|AppendViolinPlot|AppendXYZContour|AutoPositionWindow|BackgroundInfo|Beep|BezierToPolygon|BoundingBall|BoxSmooth|BrowseURL|BuildMenu|Button|cd|Chart|CheckBox|CheckDisplayed|ChooseColor|Close|CloseHelp|CloseMovie|CloseProc|ColorScale|ColorTab2Wave|Concatenate|ControlBar|ControlInfo|ControlUpdate|ConvertGlobalStringTextEncoding|ConvexHull|Convolve|CopyDimLabels|CopyFile|CopyFolder|CopyScales|Correlate|CreateAliasShortcut|CreateBrowser|Cross|CtrlBackground|CtrlFIFO|CtrlNamedBackground|Cursor|CurveFit|CustomControl|CWT|Debugger|DebuggerOptions|DefaultFont|DefaultGuiControls|DefaultGuiFont|DefaultTextEncoding|DefineGuide|DelayUpdate|DeleteAnnotations|DeleteFile|DeleteFolder|DeletePoints|Differentiate|dir|Display|DisplayHelpTopic|DisplayProcedure|DoAlert|DoIgorMenu|DoUpdate|DoWindow|DoXOPIdle|DPSS|DrawAction|DrawArc|DrawBezier|DrawLine|DrawOval|DrawPICT|DrawPoly|DrawRect|DrawRRect|DrawText|DrawUserShape|DSPDetrend|DSPPeriodogram|Duplicate|DuplicateDataFolder|DWT|EdgeStats|Edit|ErrorBars|EstimatePeakSizes|Execute|ExecuteScriptText|ExperimentInfo|ExperimentModified|ExportGizmo|Extract|FastGaussTransform|FastOp|FBinRead|FBinWrite|FFT|FGetPos|FIFO2Wave|FIFOStatus|FilterFIR|FilterIIR|FindAPeak|FindContour|FindDuplicates|FindLevel|FindLevels|FindPeak|FindPointsInPoly|FindRoots|FindSequence|FindValue|FMaxFlat|FPClustering|fprintf|FReadLine|FSetPos|FStatus|FTPCreateDirectory|FTPDelete|FTPDownload|FTPUpload|FuncFit|FuncFitMD|GBLoadWave|GetAxis|GetCamera|GetFileFolderInfo|GetGizmo|GetLastUserMenuInfo|GetMarquee|GetMouse|GetSelection|GetWindow|GraphNormal|GraphWaveDraw|GraphWaveEdit|Grep|GroupBox|Hanning|HCluster|HDF5CloseFile|HDF5CloseGroup|HDF5Control|HDF5CreateFile|HDF5CreateGroup|HDF5CreateLink|HDF5DimensionScale|HDF5Dump|HDF5DumpErrors|HDF5FlushFile|HDF5ListAttributes|HDF5ListGroup|HDF5LoadData|HDF5LoadGroup|HDF5LoadImage|HDF5OpenFile|HDF5OpenGroup|HDF5SaveData|HDF5SaveGroup|HDF5SaveImage|HDF5UnlinkObject|HideIgorMenus|HideInfo|HideProcedures|HideTools|HilbertTransform|Histogram|ICA|IFFT|ImageAnalyzeParticles|ImageBlend|ImageBoundaryToMask|ImageComposite|ImageEdgeDetection|ImageFileInfo|ImageFilter|ImageFocus|ImageFromXYZ|ImageGenerateROIMask|ImageGLCM|ImageHistModification|ImageHistogram|ImageInterpolate|ImageLineProfile|ImageLoad|ImageMorphology|ImageRegistration|ImageRemoveBackground|ImageRestore|ImageRotate|ImageSave|ImageSeedFill|ImageSkeleton3d|ImageSnake|ImageStats|ImageThreshold|ImageTransform|ImageUnwrapPhase|ImageWindow|IndexSort|InsertPoints|InstantFrequency|Integrate|Integrate2D|IntegrateODE|Interp3DPath|Interpolate2|Interpolate3D|JCAMPLoadWave|JointHistogram|JSONXOP_AddTree|JSONXOP_AddValue|JSONXOP_Dump|JSONXOP_GetArraySize|JSONXOP_GetKeys|JSONXOP_GetMaxArraySize|JSONXOP_GetType|JSONXOP_GetValue|JSONXOP_New|JSONXOP_Parse|JSONXOP_Release|JSONXOP_Remove|JSONXOP_Version|KillBackground|KillControl|KillDataFolder|KillFIFO|KillFreeAxis|KillPath|KillPICTs|KillStrings|KillVariables|KillWaves|KillWindow|KMeans|Label|Layout|LayoutPageAction|LayoutSlideShow|Legend|LinearFeedbackShiftRegister|ListBox|LoadData|LoadPackagePreferences|LoadPICT|LoadWave|Loess|LombPeriodogram|Make|MakeIndex|MarkPerfTestTime|MatrixBalance|MatrixConvolve|MatrixCorr|MatrixEigenV|MatrixFactor|MatrixFilter|MatrixGaussJ|MatrixGLM|MatrixInverse|MatrixLinearSolve|MatrixLinearSolveTD|MatrixLLS|MatrixLUBkSub|MatrixLUD|MatrixLUDTD|MatrixMultiply|MatrixMultiplyAdd|MatrixOP|MatrixReverseBalance|MatrixSchur|MatrixSolve|MatrixSparse|MatrixSVBkSub|MatrixSVD|MatrixTranspose|MeasureStyledText|MLLoadWave|Modify|ModifyBoxPlot|ModifyBrowser|ModifyCamera|ModifyContour|ModifyControl|ModifyControlList|ModifyFreeAxis|ModifyGizmo|ModifyGraph|ModifyImage|ModifyLayout|ModifyPanel|ModifyProcedure|ModifyTable|ModifyViolinPlot|ModifyWaterfall|MoveDataFolder|MoveFile|MoveFolder|MoveString|MoveSubwindow|MoveVariable|MoveWave|MoveWindow|MultiTaperPSD|MultiThreadingControl|NeuralNetworkRun|NeuralNetworkTrain|NewCamera|NewDataFolder|NewFIFO|NewFIFOChan|NewFreeAxis|NewGizmo|NewImage|NewLayout|NewMovie|NewNotebook|NewPanel|NewPath|NewWaterfall|Note|Notebook|NotebookAction|Open|OpenHelp|OpenNotebook|Optimize|ParseOperationTemplate|PathInfo|PauseForUser|PauseUpdate|PCA|PlayMovie|PlayMovieAction|PlaySound|PolygonOp|PopupContextualMenu|PopupMenu|Preferences|PrimeFactors|Print|printf|PrintGraphs|PrintLayout|PrintNotebook|PrintSettings|PrintTable|Project|PulseStats|PutScrapText|pwd|Quit|RatioFromNumber|Redimension|Remez|Remove|RemoveContour|RemoveFromGizmo|RemoveFromGraph|RemoveFromLayout|RemoveFromTable|RemoveImage|RemoveLayoutObjects|RemovePath|Rename|RenameDataFolder|RenamePath|RenamePICT|RenameWindow|ReorderImages|ReorderTraces|ReplaceText|ReplaceWave|Resample|ResumeUpdate|Reverse|Rotate|Save|SaveData|SaveExperiment|SaveGizmoCopy|SaveGraphCopy|SaveNotebook|SavePackagePreferences|SavePICT|SaveTableCopy|SetActiveSubwindow|SetAxis|SetBackground|SetDashPattern|SetDataFolder|SetDimLabel|SetDrawEnv|SetDrawLayer|SetFileFolderInfo|SetFormula|SetIdlePeriod|SetIgorHook|SetIgorMenuMode|SetIgorOption|SetMarquee|SetProcessSleep|SetRandomSeed|SetScale|SetVariable|SetWaveLock|SetWaveTextEncoding|SetWindow|ShowIgorMenus|ShowInfo|ShowTools|Silent|Sleep|Slider|Smooth|SmoothCustom|Sort|SortColumns|SoundInRecord|SoundInSet|SoundInStartChart|SoundInStatus|SoundInStopChart|SoundLoadWave|SoundSaveWave|SphericalInterpolate|SphericalTriangulate|SplitString|SplitWave|sprintf|sscanf|Stack|StackWindows|StatsAngularDistanceTest|StatsANOVA1Test|StatsANOVA2NRTest|StatsANOVA2RMTest|StatsANOVA2Test|StatsChiTest|StatsCircularCorrelationTest|StatsCircularMeans|StatsCircularMoments|StatsCircularTwoSampleTest|StatsCochranTest|StatsContingencyTable|StatsDIPTest|StatsDunnettTest|StatsFriedmanTest|StatsFTest|StatsHodgesAjneTest|StatsJBTest|StatsKDE|StatsKendallTauTest|StatsKSTest|StatsKWTest|StatsLinearCorrelationTest|StatsLinearRegression|StatsMultiCorrelationTest|StatsNPMCTest|StatsNPNominalSRTest|StatsQuantiles|StatsRankCorrelationTest|StatsResample|StatsSample|StatsScheffeTest|StatsShapiroWilkTest|StatsSignTest|StatsSRTest|StatsTTest|StatsTukeyTest|StatsVariancesTest|StatsWatsonUSquaredTest|StatsWatsonWilliamsTest|StatsWheelerWatsonTest|StatsWilcoxonRankTest|StatsWRCorrelationTest|STFT|String|StructFill|StructGet|StructPut|SumDimension|SumSeries|TabControl|Tag|Text2Bezier|TextBox|TextHistogram|ThreadGroupPutDF|ThreadStart|TickWavesFromAxis|Tile|TileWindows|TitleBox|ToCommandLine|ToolsGrid|Triangulate3d|Unwrap|UnzipFile|URLRequest|ValDisplay|Variable|WaveMeanStdv|WaveStats|WaveTracking|WaveTransform|wfprintf|WignerTransform|WindowFunction|XLLoadWave)(?:.*)/i,
      greedy: true,
      inside: {
        'regex': /\/[A-Za-z]\w*(?![^(]*\))/, //flag (not highlighted in Igor itself)
        'function': /^[A-Za-z]\w*/,
        'string': str,
        'number': num,
        'operator': op,
        'punctuation': punc,
      },
    },
  };
}(Prism));
